#include "ui_polyline.h"
#include "ui_manager.h"

//polyline specific includes

#include "math/interpolation.h"


//polyline of graph specific includes


#include "audio/audio.h"
#include "graphics/graphics_util.h"

#include "util/timer.h"		    // Needs to come in early
#include "util/mmgr.h"		    // Needs to come in early
#include "util/common_macros.h"		// macros
#include "util/log.h"		    // logging

#include "script/scripthelper.h"
#include "script/write_lua.h"

#ifdef _ENABLE_LUABIND
#include <luabind/luabind.hpp>
#endif // _ENABLE_LUABIND


using namespace ui;
using namespace script;
using namespace LuaPlus;



//UIPolyLine: Constructor and destructor
//======================================================================================================================

UIPolyLine::UIPolyLine(UIWidget* pParent,const std::string& Name):
	UIWidget(pParent, Name),
	m_LineWidth(1.0f/(float)GraphicsUtil::WIDTH, 1.0f/(float)GraphicsUtil::HEIGHT),
	m_SpriteSegment(),
	m_SegmentColor(0.0f,0.0f,0.0f,0.0f),
	m_SegmentAdditive(false),
	m_CurAnimFactor(1.0f)
{
	m_Type = WT_POLYLINE;

}//UIPolyLine::UIPolyLine(UIWidget* pParent,const std::string& Name = "")


UIPolyLine::~UIPolyLine()
{

	//params uninit

}//UIPolyLine::~UIPolyLine()


//UIPolyLine: Common routines
//======================================================================================================================


bool UIPolyLine::Create(const std::string& Name, const math::Vec2& Pos, const math::Vec2& Size)
{

	UIWidget::Create(Name, Pos, Size);
	// create progress stuff

	return true;


}//bool UIPolyLine::Create(const std::string& Name, const math::Vec2& Pos, const math::Vec2& Size)



bool UIPolyLine::Load(LuaPlus::LuaObject& _LObj)
{

	UIWidget::Load(_LObj);	// get all the common stuff loaded
	
	//polyline-specific stuff


	//line width
	m_LineWidth = ScriptHelper::GetTableVec2(_LObj, "LineWidth", math::Vec2(1.0f/(float)GraphicsUtil::WIDTH, 1.0f/(float)GraphicsUtil::HEIGHT));

	//line points
	LuaObject PointsTable = ScriptHelper::GetObj(_LObj, "Points");

	if (PointsTable.IsTable() == true)
	{
		int i;
		int PointsCount = PointsTable.GetCount();

		if (PointsCount > 1)
		{

			
			for (i = 0; i < PointsCount; i++)
			{
				LuaPlus::LuaObject TempObj = PointsTable[i+1];
				m_LinePoints.push_back(ScriptHelper::GetVec2(TempObj , math::Vec2(0.0f,0.0f)));
			}
		}
	}
	
	//line segment sprite settings
	//image
	std::string SegmentImage = ScriptHelper::GetTableString(_LObj, "SegmentImage");

	if (SegmentImage != "")
		m_SpriteSegment.SetImage(SegmentImage);

	//color
	m_SegmentColor = ScriptHelper::GetTableVec4(_LObj, "SegmentColor", math::Vec4(1.0f,1.0f,1.0f,1.0f));

	//additive
	m_SpriteSegment.SetAdditive(ScriptHelper::GetTableBool(_LObj, "SegmentAdditive", false)); 	

	//UVs
	m_SpriteSegment.SetUV();

	return true;
}





//UIPolyLine: Update and Render
//======================================================================================================================

bool UIPolyLine::Tick(float dt)
{
	UIWidget::Tick(dt);	// tick children, etc

	//TODO add anim factor



	return true;
}


bool UIPolyLine::Render(bool Force)
{

	UIWidget::Render(Force); //rendering common stuff

	if (!Force)
	{
		// look for things that could disqualify this one from being rendered
		if (!m_IsVisible)
			return false;	// disable entire widget
		if (m_pManager->GetDragTarget() == this)
			return false;	// will get rendered on top anyways
	}

	//setting initial sprite params
	m_SpriteSegment.SetVisible(true);

	//calculating cur column color
	COLOR CurColor = ColorfRGBA(m_SegmentColor.x, m_SegmentColor.y, m_SegmentColor.z, m_SegmentColor.w * m_CurAnimFactor);

	m_SpriteSegment.SetColor(CurColor);


	//iterating through line points
	std::list<math::Vec2>::iterator CurPointIter = m_LinePoints.begin();
	std::list<math::Vec2>::iterator NextPointIter = CurPointIter;
	NextPointIter++;

	bool LineIsValid;

	while(NextPointIter != m_LinePoints.end())
	{
		math::Vec2 CurPoint = (*CurPointIter) + m_Pos;
		math::Vec2 NextPoint= (*NextPointIter)+ m_Pos;

		LineIsValid = false;

		//line - up
		if (CurPoint.x == NextPoint.x && CurPoint.y > NextPoint.y)
		{
			//line is valid
			LineIsValid = true;

			//setting up quad
			m_SpriteSegment.Quad_SetupTLBR(NextPoint - m_LineWidth * 0.5f, CurPoint + m_LineWidth * 0.5f);  
		}

		//line - right
		if (CurPoint.y == NextPoint.y && CurPoint.x < NextPoint.x)
		{
			//line is valid
			LineIsValid = true;

			//setting up quad
			m_SpriteSegment.Quad_SetupTLBR(CurPoint - m_LineWidth * 0.5f, NextPoint + m_LineWidth * 0.5f);
		}

		//line - down
		if (CurPoint.x == NextPoint.x && CurPoint.y < NextPoint.y)
		{
			//line is valid
			LineIsValid = true;

			//setting up quad
			m_SpriteSegment.Quad_SetupTLBR(CurPoint - m_LineWidth * 0.5f, NextPoint + m_LineWidth * 0.5f);
		}

		//line - left
		if (CurPoint.y == NextPoint.y && CurPoint.x > NextPoint.x)
		{
			//line is valid
			LineIsValid = true;

			//setting up quad
			m_SpriteSegment.Quad_SetupTLBR(NextPoint - m_LineWidth * 0.5f, CurPoint + m_LineWidth * 0.5f);  
		}

		if (LineIsValid == true)
		{
			m_SpriteSegment.Render();
		}

		CurPointIter++;
		NextPointIter++;

	}

	return true;

}








void UIPolyLine::Register(LuaPlus::LuaState* _pScript)
{
#ifdef _ENABLE_LUABIND    

	
#endif // _ENABLE_LUABIND    
}//void UIPolyLine::Register(LuaPlus::LuaState* _pScript)





